#include <iostream>
#include <pthread.h>
#include <unistd.h>
using namespace std;

// pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
// pthread_cond_t cond = PTHREAD_COND_INITIALIZER;

// void *thread_run(void *args)
// {
//     const char *data = static_cast<const char *>(args);
//     while (1)
//     {
//         pthread_mutex_lock(&mutex);
//         pthread_cond_wait(&cond,&mutex);
//         cout << data << endl;
//         sleep(1);
//         pthread_mutex_unlock(&mutex);
//     }
// }
// int main()
// {
//     pthread_t tid_A;
//     pthread_t tid_B;
//     pthread_create(&tid_A, nullptr, thread_run, (void *)"我是线程A");
//     pthread_create(&tid_B, nullptr, thread_run, (void *)"我是线程B");
//     while(1)
//     {
//         // pthread_cond_signal(&cond);
//         pthread_cond_broadcast(&cond);
//     }

//     pthread_join(tid_A, nullptr);
//     pthread_join(tid_B, nullptr);

//     return 0;
// }


//***三个线程共用一个实例的解释
// 定义共享的数据结构
typedef struct {
    int value;
    pthread_mutex_t mutex;
} Foo;

// 初始化Foo实例
void foo_init(Foo *foo) {
    foo->value = 0;
    pthread_mutex_init(&foo->mutex, NULL);
}

// 线程函数，每个线程对Foo实例的值进行增加操作
void *thread_function(void *arg) {
    Foo *foo = (Foo *)arg;

    // 对共享资源加锁
    pthread_mutex_lock(&foo->mutex);

    // 对Foo实例的值进行增加操作
    foo->value += 1;
    printf("Thread ID %ld: Foo value is now %d\n", pthread_self(), foo->value);

    // 解锁共享资源
    pthread_mutex_unlock(&foo->mutex);

    // 线程退出
    pthread_exit(NULL);
}

int main() {
    Foo foo_instance;
    foo_init(&foo_instance);

    pthread_t thread_a, thread_b, thread_c;

    // 创建线程A
    pthread_create(&thread_a, NULL, thread_function, (void *)&foo_instance);
    // 创建线程B
    pthread_create(&thread_b, NULL, thread_function, (void *)&foo_instance);
    // 创建线程C
    pthread_create(&thread_c, NULL, thread_function, (void *)&foo_instance);

    // 等待线程A结束
    pthread_join(thread_a, NULL);
    // 等待线程B结束
    pthread_join(thread_b, NULL);
    // 等待线程C结束
    pthread_join(thread_c, NULL);

    // 销毁互斥锁
    pthread_mutex_destroy(&foo_instance.mutex);

    return 0;
}